package com.bzkj.basicinfo.service.inspect.impl;

import com.bzkj.basicinfo.domain.inspect.WmsInspectDetailEntity;
import com.bzkj.basicinfo.domain.inspect.WmsInspectTaskEntity;
import com.bzkj.basicinfo.domain.receive.WmsReceiveOrderEntity;
import com.bzkj.basicinfo.domain.receive.WmsReceiveOrderDetailEntity;
import com.bzkj.basicinfo.mapper.inspect.WmsInspectDetailMapper;
import com.bzkj.basicinfo.mapper.inspect.WmsInspectTaskMapper;
import com.bzkj.basicinfo.mapper.receive.WmsReceiveOrderMapper;
import com.bzkj.basicinfo.mapper.receive.WmsReceiveOrderDetailMapper;
import com.bzkj.basicinfo.service.putaway.WmsPutawayTaskService;
import com.bzkj.basicinfo.service.exception.WmsExceptionRecordService;
import com.bzkj.common.core.domain.AjaxResult;
import com.bzkj.common.utils.PageUtils;
import com.bzkj.common.core.page.TableDataInfo;
import com.bzkj.common.utils.SecurityUtils;
import com.bzkj.basicinfo.service.inspect.WmsInspectTaskService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class WmsInspectTaskServiceImpl implements WmsInspectTaskService {

    @Autowired
    private WmsInspectTaskMapper inspectTaskMapper;

    @Autowired
    private WmsInspectDetailMapper inspectDetailMapper;

    @Autowired
    private WmsReceiveOrderMapper receiveOrderMapper;

    @Autowired
    private WmsReceiveOrderDetailMapper receiveOrderDetailMapper;

    @Autowired
    private WmsPutawayTaskService putawayTaskService;

    @Autowired
    private WmsExceptionRecordService exceptionRecordService;

    @Override
    public TableDataInfo getInspectTaskList(WmsInspectTaskEntity entity, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<WmsInspectTaskEntity> list = inspectTaskMapper.selectInspectTaskList(entity);
        PageInfo<WmsInspectTaskEntity> pageInfo = new PageInfo<>(list);
        return PageUtils.getTableDataInfo(pageInfo);
    }

    @Override
    public WmsInspectTaskEntity getInspectTaskDetail(Long id) {
        return inspectTaskMapper.selectInspectTaskById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int createInspectTask(Long receiveOrderId, String inspectType) {
        String taskNo = "INSP" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());

        WmsInspectTaskEntity entity = new WmsInspectTaskEntity();
        entity.setTaskNo(taskNo);
        entity.setReceiveOrderId(receiveOrderId);
        entity.setInspectType(inspectType != null ? inspectType : "full");
        entity.setTaskStatus("pending");
        entity.setCreateBy(SecurityUtils.getUsername());
        entity.setCreateTime(new Date());

        return inspectTaskMapper.insertInspectTask(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int completeInspectTask(Long id) {
        WmsInspectTaskEntity entity = new WmsInspectTaskEntity();
        entity.setId(id);
        entity.setTaskStatus("completed");
        entity.setCompleteTime(new Date());
        return inspectTaskMapper.updateInspectTask(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteInspectTask(Long id) {
        inspectDetailMapper.deleteDetailsByTaskId(id);
        return inspectTaskMapper.deleteInspectTaskById(id);
    }

    @Override
    public TableDataInfo getPendingReceiveOrders(Map<String, Object> params) {
        Integer pageNum = Integer.parseInt(params.getOrDefault("pageNum", "1").toString());
        Integer pageSize = Integer.parseInt(params.getOrDefault("pageSize", "10").toString());

        PageHelper.startPage(pageNum, pageSize);

        // 查询已收货但未验收的收货单
        WmsReceiveOrderEntity queryEntity = new WmsReceiveOrderEntity();
        queryEntity.setOrderStatus("1"); // 已到货状态

        List<WmsReceiveOrderEntity> list = receiveOrderMapper.selectPendingInspectOrders(queryEntity);
        PageInfo<WmsReceiveOrderEntity> pageInfo = new PageInfo<>(list);
        return PageUtils.getTableDataInfo(pageInfo);
    }

    /**
     * 获取待验收的验收任务列表（用于验收界面选择）
     */
    @Override
    public TableDataInfo getPendingInspectTasks(Map<String, Object> params) {
        Integer pageNum = Integer.parseInt(params.getOrDefault("pageNum", "1").toString());
        Integer pageSize = Integer.parseInt(params.getOrDefault("pageSize", "10").toString());

        PageHelper.startPage(pageNum, pageSize);

        // 查询待验收和验收中的任务
        WmsInspectTaskEntity queryEntity = new WmsInspectTaskEntity();

        String taskStatus = (String) params.get("taskStatus");
        if (taskStatus != null && !taskStatus.isEmpty()) {
            queryEntity.setTaskStatus(taskStatus);
        } else {
            // 默认查询待验收和验收中的任务
            // 这里需要在Mapper中支持多状态查询，或者分两次查询
            queryEntity.setTaskStatus("pending"); // 暂时只查询待验收
        }

        String receiveOrderNo = (String) params.get("receiveOrderNo");
        if (receiveOrderNo != null && !receiveOrderNo.isEmpty()) {
            queryEntity.setReceiveOrderNo(receiveOrderNo);
        }

        List<WmsInspectTaskEntity> list = inspectTaskMapper.selectInspectTaskList(queryEntity);
        PageInfo<WmsInspectTaskEntity> pageInfo = new PageInfo<>(list);
        return PageUtils.getTableDataInfo(pageInfo);
    }

    @Override
    public Map<String, Object> getReceiveOrderDetailForInspect(Long receiveOrderId) {
        Map<String, Object> result = new HashMap<>();
        
        // 查询收货单主表信息
        WmsReceiveOrderEntity receiveOrder = receiveOrderMapper.selectReceiveOrderById(receiveOrderId);
        if (receiveOrder == null) {
            result.put("success", false);
            result.put("message", "收货单不存在");
            return result;
        }
        
        // 查询收货单明细
        WmsReceiveOrderDetailEntity queryDetail = new WmsReceiveOrderDetailEntity();
        queryDetail.setReceiveOrderId(receiveOrderId);
        List<WmsReceiveOrderDetailEntity> detailList = receiveOrderDetailMapper.selectReceiveDetailList(queryDetail);
        
        result.put("success", true);
        result.put("receiveOrder", receiveOrder);
        result.put("detailList", detailList);
        
        return result;
    }

    @Override
    public Map<String, Object> getShelfInfoByProduct(String productId) {
        Map<String, Object> result = new HashMap<>();
        
        // 这里应该查询货位信息，暂时返回模拟数据
        // TODO: 实现货位查询逻辑
        List<Map<String, Object>> shelfList = new ArrayList<>();
        Map<String, Object> shelf1 = new HashMap<>();
        shelf1.put("shelfCode", "A-01-01");
        shelf1.put("shelfName", "A区1排1层");
        shelf1.put("available", true);
        shelfList.add(shelf1);
        
        Map<String, Object> shelf2 = new HashMap<>();
        shelf2.put("shelfCode", "A-01-02");
        shelf2.put("shelfName", "A区1排2层");
        shelf2.put("available", true);
        shelfList.add(shelf2);
        
        result.put("success", true);
        result.put("shelfList", shelfList);
        
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    public Long submitInspect(Long receiveOrderId, String receiveOrderNo, List<WmsInspectDetailEntity> details) {
        try {
            // 1. 验证收货单状态，必须是已到货状态（1）
            WmsReceiveOrderEntity receiveOrder = receiveOrderMapper.selectReceiveOrderById(receiveOrderId);
            if (receiveOrder == null) {
                throw new RuntimeException("收货单不存在");
            }
            if (!"1".equals(receiveOrder.getOrderStatus())) {
                throw new RuntimeException("只有已到货状态的收货单才能验收，当前状态：" + receiveOrder.getOrderStatus());
            }

            // 2. 创建验收任务
            String taskNo = "INSP" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());

            WmsInspectTaskEntity inspectTask = new WmsInspectTaskEntity();
            inspectTask.setTaskNo(taskNo);
            inspectTask.setReceiveOrderId(receiveOrderId);
            inspectTask.setReceiveOrderNo(receiveOrderNo);
            inspectTask.setInspectType("manual"); // 手动验收
            inspectTask.setTaskStatus("completed");
            inspectTask.setPriority(1);
            inspectTask.setAssignedUser(SecurityUtils.getUsername());
            inspectTask.setStartTime(new Date());
            inspectTask.setCompleteTime(new Date());
            inspectTask.setTotalLines(details.size());
            inspectTask.setInspectedLines(details.size());

            // 计算总数量和合格数量
            BigDecimal totalQuantity = BigDecimal.ZERO;
            BigDecimal qualifiedQuantity = BigDecimal.ZERO;
            BigDecimal unqualifiedQuantity = BigDecimal.ZERO;

            for (WmsInspectDetailEntity detail : details) {
                if (detail.getInspectQuantity() == null) {
                    throw new RuntimeException("商品[" + detail.getProductName() + "]的验收数量不能为空");
                }
                if (detail.getQualifiedQuantity() == null) {
                    throw new RuntimeException("商品[" + detail.getProductName() + "]的合格数量不能为空");
                }
                if (detail.getUnqualifiedQuantity() == null) {
                    detail.setUnqualifiedQuantity(BigDecimal.ZERO);
                }

                totalQuantity = totalQuantity.add(detail.getInspectQuantity());
                qualifiedQuantity = qualifiedQuantity.add(detail.getQualifiedQuantity());
                unqualifiedQuantity = unqualifiedQuantity.add(detail.getUnqualifiedQuantity());
            }

            inspectTask.setTotalQuantity(totalQuantity);
            inspectTask.setInspectedQuantity(totalQuantity);
            inspectTask.setQualifiedQuantity(qualifiedQuantity);
            inspectTask.setUnqualifiedQuantity(unqualifiedQuantity);
            inspectTask.setCreateBy(SecurityUtils.getUsername());
            inspectTask.setCreateTime(new Date());

            int taskRows = inspectTaskMapper.insertInspectTask(inspectTask);
            if (taskRows <= 0) {
                throw new RuntimeException("创建验收任务失败");
            }

            // 3. 保存验收明细
            for (int i = 0; i < details.size(); i++) {
                WmsInspectDetailEntity detail = details.get(i);
                detail.setInspectTaskId(inspectTask.getId());
                detail.setTaskNo(taskNo);
                detail.setLineNo(i + 1);
                detail.setDetailStatus("completed");
                detail.setInspectTime(new Date());
                detail.setInspector(SecurityUtils.getUsername());
                detail.setCreateBy(SecurityUtils.getUsername());
                detail.setCreateTime(new Date());

                // 计算不合格数量
                if (detail.getUnqualifiedQuantity() == null) {
                    detail.setUnqualifiedQuantity(
                        detail.getInspectQuantity().subtract(detail.getQualifiedQuantity())
                    );
                }

                int detailRows = inspectDetailMapper.insertInspectDetail(detail);
                if (detailRows <= 0) {
                    throw new RuntimeException("保存验收明细失败");
                }
            }

            // 4. 更新收货单状态为已完成验收（2）
            WmsReceiveOrderEntity updateOrder = new WmsReceiveOrderEntity();
            updateOrder.setId(receiveOrderId);
            updateOrder.setOrderStatus("2"); // 已完成验收
            updateOrder.setUpdateBy(SecurityUtils.getUsername());
            updateOrder.setUpdateTime(new Date());
            receiveOrderMapper.updateReceiveOrder(updateOrder);

            // 5. 创建上架任务（批量创建）
            try {
                putawayTaskService.batchCreatePutawayTask(receiveOrderId, SecurityUtils.getUsername());
            } catch (Exception e) {
                // 记录日志但不回滚验收操作
                // 上架任务可以后续手动创建
                System.err.println("创建上架任务失败：" + e.getMessage());
            }

            return inspectTask.getId();

        } catch (Exception e) {
            throw new RuntimeException("提交验收失败：" + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchUpdateInspectDetails(List<WmsInspectDetailEntity> details) {
        if (details == null || details.isEmpty()) {
            return 0;
        }

        for (WmsInspectDetailEntity detail : details) {
            detail.setUpdateBy(SecurityUtils.getUsername());
            detail.setUpdateTime(new Date());
        }

        return inspectDetailMapper.batchUpdateInspectDetails(details);
    }

    /**
     * 根据收货单创建验收任务（确认到货时调用）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createInspectTaskForReceiveOrder(Long receiveOrderId, String receiveOrderNo, String operator) {
        try {
            // 1. 查询收货单信息
            WmsReceiveOrderEntity receiveOrder = receiveOrderMapper.selectReceiveOrderById(receiveOrderId);
            if (receiveOrder == null) {
                throw new RuntimeException("收货单不存在");
            }

            // 2. 查询收货单明细
            WmsReceiveOrderDetailEntity queryDetail = new WmsReceiveOrderDetailEntity();
            queryDetail.setReceiveOrderId(receiveOrderId);
            List<WmsReceiveOrderDetailEntity> detailList = receiveOrderDetailMapper.selectReceiveDetailList(queryDetail);

            if (detailList == null || detailList.isEmpty()) {
                throw new RuntimeException("收货单明细不存在");
            }

            // 3. 生成验收任务号
            String taskNo = "INSP" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());

            // 4. 创建验收任务
            WmsInspectTaskEntity inspectTask = new WmsInspectTaskEntity();
            inspectTask.setTaskNo(taskNo);
            inspectTask.setReceiveOrderId(receiveOrderId);
            inspectTask.setReceiveOrderNo(receiveOrderNo);
            inspectTask.setStoId(receiveOrder.getStoId());
            inspectTask.setInspectType("full"); // 全检
            inspectTask.setTaskStatus("pending"); // 待验收
            inspectTask.setPriority(1);
            inspectTask.setAssignedUser(operator);
            inspectTask.setAssignTime(new Date());
            inspectTask.setTotalLines(detailList.size());
            inspectTask.setInspectedLines(0);

            // 计算总数量
            BigDecimal totalQuantity = BigDecimal.ZERO;
//            for (WmsReceiveOrderDetailEntity detail : detailList) {
//                if (detail.getReceiveQuantity() != null) {
//                    totalQuantity = totalQuantity.add(detail.getReceiveQuantity());
//                }
//            }

            inspectTask.setTotalQuantity(totalQuantity);
            inspectTask.setInspectedQuantity(BigDecimal.ZERO);
            inspectTask.setQualifiedQuantity(BigDecimal.ZERO);
            inspectTask.setUnqualifiedQuantity(BigDecimal.ZERO);
            inspectTask.setCreateBy(operator);
            inspectTask.setCreateTime(new Date());

            int rows = inspectTaskMapper.insertInspectTask(inspectTask);
            if (rows <= 0) {
                throw new RuntimeException("创建验收任务失败");
            }

            return inspectTask.getId();

        } catch (Exception e) {
            throw new RuntimeException("创建验收任务失败：" + e.getMessage(), e);
        }
    }

    /**
     * 验收不通过处理（新增方法）
     * 将收货单状态回滚至「4 - 异常」，记录不通过原因、人员、时间
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult rejectInspect(Long receiveOrderId, String receiveOrderNo,
                                  String rejectReason, String rejectDesc,
                                  String photoUrls, String operator) {
        try {
            // 1. 验证收货单状态，必须是已到货状态（1）
            WmsReceiveOrderEntity receiveOrder = receiveOrderMapper.selectReceiveOrderById(receiveOrderId);
            if (receiveOrder == null) {
                return AjaxResult.error("收货单不存在");
            }
            if (!"1".equals(receiveOrder.getOrderStatus())) {
                return AjaxResult.error("只有已到货状态的收货单才能进行验收不通过操作，当前状态：" + receiveOrder.getOrderStatus());
            }

            // 2. 更新收货单状态为异常（4）
            WmsReceiveOrderEntity updateOrder = new WmsReceiveOrderEntity();
            updateOrder.setId(receiveOrderId);
            updateOrder.setOrderStatus("4"); // 异常状态
            updateOrder.setUpdateBy(operator);
            updateOrder.setUpdateTime(new Date());

            int rows = receiveOrderMapper.updateReceiveOrder(updateOrder);
            if (rows <= 0) {
                return AjaxResult.error("更新收货单状态失败");
            }

            // 3. 创建验收任务记录（标记为不通过）
            String taskNo = "INSP" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());

            WmsInspectTaskEntity inspectTask = new WmsInspectTaskEntity();
            inspectTask.setTaskNo(taskNo);
            inspectTask.setReceiveOrderId(receiveOrderId);
            inspectTask.setReceiveOrderNo(receiveOrderNo);
            inspectTask.setInspectType("manual"); // 手动验收
            inspectTask.setTaskStatus("rejected"); // 已拒绝
            inspectTask.setPriority(1);
            inspectTask.setAssignedUser(operator);
            inspectTask.setStartTime(new Date());
            inspectTask.setCompleteTime(new Date());
            inspectTask.setTotalLines(0);
            inspectTask.setInspectedLines(0);
            inspectTask.setTotalQuantity(BigDecimal.ZERO);
            inspectTask.setInspectedQuantity(BigDecimal.ZERO);
            inspectTask.setQualifiedQuantity(BigDecimal.ZERO);
            inspectTask.setUnqualifiedQuantity(BigDecimal.ZERO);
            inspectTask.setCreateBy(operator);
            inspectTask.setCreateTime(new Date());

            int taskRows = inspectTaskMapper.insertInspectTask(inspectTask);
            if (taskRows <= 0) {
                return AjaxResult.error("创建验收任务记录失败");
            }

            // 4. 创建异常记录
            try {
                String exceptionTitle = "验收不通过：" + receiveOrderNo;
                String exceptionDesc = "收货单[" + receiveOrderNo + "]验收不通过，原因：" + rejectReason;
                if (rejectDesc != null && !rejectDesc.isEmpty()) {
                    exceptionDesc += "，详细描述：" + rejectDesc;
                }

                AjaxResult exceptionResult = exceptionRecordService.createExceptionRecord(
                    "inspect_reject", // 异常类型：验收不通过
                    "receive_order", // 关联单据类型：收货单
                    receiveOrderNo, // 关联单据号
                    receiveOrderId, // 关联单据ID
                    exceptionTitle, // 异常标题
                    exceptionDesc, // 异常描述
                    rejectReason, // 异常原因
                    operator // 操作人
                );

                if (!exceptionResult.isSuccess()) {
                    // 异常记录创建失败不回滚主业务，只记录日志
                    System.err.println("创建异常记录失败：" + exceptionResult.get("msg"));
                }
            } catch (Exception e) {
                // 异常记录创建失败不回滚主业务，只记录日志
                System.err.println("创建异常记录异常：" + e.getMessage());
            }

            return AjaxResult.success("验收不通过处理成功，收货单状态已更新为异常", taskNo);

        } catch (Exception e) {
            throw new RuntimeException("验收不通过处理失败：" + e.getMessage(), e);
        }
    }

    /**
     * 异常收货单重新验收（新增方法）
     * 将异常状态的收货单重新设置为已到货待验收状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult resetInspectStatus(Long receiveOrderId, String operator) {
        try {
            // 1. 验证收货单状态，必须是异常状态（4）
            WmsReceiveOrderEntity receiveOrder = receiveOrderMapper.selectReceiveOrderById(receiveOrderId);
            if (receiveOrder == null) {
                return AjaxResult.error("收货单不存在");
            }
            if (!"4".equals(receiveOrder.getOrderStatus())) {
                return AjaxResult.error("只有异常状态的收货单才能重新验收，当前状态：" + receiveOrder.getOrderStatus());
            }

            // 2. 更新收货单状态为已到货待验收（1）
            WmsReceiveOrderEntity updateOrder = new WmsReceiveOrderEntity();
            updateOrder.setId(receiveOrderId);
            updateOrder.setOrderStatus("1"); // 已到货待验收
            updateOrder.setUpdateBy(operator);
            updateOrder.setUpdateTime(new Date());

            int rows = receiveOrderMapper.updateReceiveOrder(updateOrder);
            if (rows <= 0) {
                return AjaxResult.error("更新收货单状态失败");
            }

            // 3. 创建新的验收任务
            try {
                Long inspectTaskId = createInspectTaskForReceiveOrder(
                    receiveOrderId,
                    receiveOrder.getReceiveOrderNo(),
                    operator
                );

                return AjaxResult.success("重置验收状态成功，已创建新的验收任务", inspectTaskId);
            } catch (Exception e) {
                // 如果创建验收任务失败，抛出异常回滚整个事务
                throw new RuntimeException("创建验收任务失败：" + e.getMessage(), e);
            }

        } catch (Exception e) {
            throw new RuntimeException("重置验收状态失败：" + e.getMessage(), e);
        }
    }
}
